/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entities;

import interfaces.CandidateCapable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author damfercer
 */
@Entity
@Table(name = "candidate")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Candidate.findAll", query = "SELECT c FROM Candidate c"),
    @NamedQuery(name = "Candidate.findByIdCandidate", query = "SELECT c FROM Candidate c WHERE c.idCandidate = :idCandidate"),
    @NamedQuery(name = "Candidate.findByName", query = "SELECT c FROM Candidate c WHERE c.name = :name"),
    @NamedQuery(name = "Candidate.findByLastName", query = "SELECT c FROM Candidate c WHERE c.lastName = :lastName"),
    @NamedQuery(name = "Candidate.findByBirthDay", query = "SELECT c FROM Candidate c WHERE c.birthDay = :birthDay"),
    @NamedQuery(name = "Candidate.findByHeight", query = "SELECT c FROM Candidate c WHERE c.height = :height"),
    @NamedQuery(name = "Candidate.findByWeight", query = "SELECT c FROM Candidate c WHERE c.weight = :weight"),
    @NamedQuery(name = "Candidate.findByBustColor", query = "SELECT c FROM Candidate c WHERE c.bustColor = :bustColor"),
    @NamedQuery(name = "Candidate.findByNoPictures", query = "SELECT c FROM Candidate c WHERE c.bustColor IS NULL OR c.bustBlackWhite IS NULL OR c.bodyFormal IS NULL"),
    @NamedQuery(name = "Candidate.findByBustBlackWhite", query = "SELECT c FROM Candidate c WHERE c.bustBlackWhite = :bustBlackWhite"),
    @NamedQuery(name = "Candidate.findByBodyFormal", query = "SELECT c FROM Candidate c WHERE c.bodyFormal = :bodyFormal"),
    @NamedQuery(name = "Candidate.findByBodyUnformal", query = "SELECT c FROM Candidate c WHERE c.bodyUnformal = :bodyUnformal"),
    @NamedQuery(name = "Candidate.findByLastModificationDate", query = "SELECT c FROM Candidate c WHERE c.lastModificationDate = :lastModificationDate")})

public class Candidate implements Comparable<Candidate>,Serializable,CandidateCapable {
    @Size(max = 280)
    @Column(name = "DESCRIPTION")
    private String description;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy = "candidate")
    private List<CandidateSearchInterest> candidateSearchInterestList;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy = "candidate")
    private List<CandidateTags> candidateTagsList;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "candidate")
    private PublicRelationsCandidate publicRelationsCandidate;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "candidate")
    private CandidateConfiguration candidateConfiguration;
    @JoinColumn(name = "WORKING_STATUS", referencedColumnName = "ID_WORKING_STATUS")
    @ManyToOne(fetch = FetchType.LAZY)
    private WorkingStatus workingStatus;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idCandidate", fetch = FetchType.LAZY)
    private List<CompanyVisitedProfile> companyVisitedProfileList;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy = "candidate", fetch = FetchType.LAZY)
    private List<CandidateBookImage> candidateBookImageList;
    @Column(name = "HAS_VEHICLE")
    private Boolean hasVehicle;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "candidate", fetch = FetchType.LAZY)
    private List<CompanyAdquiredProfile> companyAdquiredProfileList;
    @Column(name = "VISITS")
    private Integer visits;
    @JoinColumn(name = "TIME_AVAILABILITY", referencedColumnName = "ID_TIME_AVAILABILITY")
    @ManyToOne(fetch = FetchType.LAZY)
    private TimeAvailability timeAvailability;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy = "candidate", fetch = FetchType.LAZY)
    private List<CandidateInterestArea> candidateInterestAreaList;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy = "candidate", fetch = FetchType.LAZY)
    private List<CandidateRelocatingInfo> candidateRelocatingInfoList;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy = "candidate", fetch = FetchType.LAZY)
    private List<CandidateLanguageInfo> candidateLanguageInfoList;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy = "candidate", fetch = FetchType.LAZY)
    private List<CandidateProfessionalInfo> candidateProfessionalInfoList;
    // @Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$", message="Invalid phone/fax format, should be as xxx-xxx-xxxx")//if the field contains phone or fax number consider using this annotation to enforce field validation
    @Basic(optional = true)
    //@NotNull
    @Size(min = 1, max = 20)
    @Column(name = "PHONE")
    private String phone;
    @JoinColumn(name = "CANDIDATE_TYPE", referencedColumnName = "ID_CANDIDATE_TYPE")
    @ManyToOne(fetch = FetchType.LAZY)
    private CandidateType candidateType;
    @JoinColumn(name = "CANDIDATE_ECONOMIC_TYPE", referencedColumnName = "ID_CANDIDATE_ECONOMIC_TYPE")
    @ManyToOne(fetch = FetchType.LAZY)
    private CandidateEconomicType candidateEconomicType;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "candidate", orphanRemoval=true, fetch = FetchType.LAZY)
    private List<CandidateEducationalInfo> candidateEducationalInfoList;
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = true)
    @Column(name = "ID_CANDIDATE")
    private Integer idCandidate;
    @Basic(optional = true)
    //@NotNull
    @Size(min = 1, max = 30)
    @Column(name = "NAME")
    private String name;
    @Basic(optional = true)
    //@NotNull
    @Size(min = 1, max = 60)
    @Column(name = "LAST_NAME")
    private String lastName;
    @Basic(optional = true)
    //@NotNull
    @Column(name = "BIRTH_DAY")
    @Temporal(TemporalType.DATE)
    private Date birthDay;
    @Basic(optional = true)
    @Column(name = "HEIGHT")
    private Long height;
    @Basic(optional = true)
    @Column(name = "WEIGHT")
    private Long weight;
    @Basic(optional = true)
    @Size(min = 1, max = 100)
    @Column(name = "BUST_COLOR")
    private String bustColor;
    @Basic(optional = true)
    @Size(min = 1, max = 100)
    @Column(name = "BUST_BLACK_WHITE")
    private String bustBlackWhite;
    @Basic(optional = true)
    @Size(min = 1, max = 100)
    @Column(name = "BODY_FORMAL")
    private String bodyFormal;
    @Basic(optional = true)
    @Size(min = 1, max = 100)
    @Column(name = "BODY_UNFORMAL")
    private String bodyUnformal;
    @Basic(optional = true)
    @Column(name = "LAST_MODIFICATION_DATE")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModificationDate;
    @JoinColumn(name = "TOWN", referencedColumnName = "ID_TOWN")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Town town;
    @JoinColumn(name = "PROVINCE", referencedColumnName = "ID_PROVINCE")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Province province;
    @JoinColumn(name = "COUNTRY", referencedColumnName = "ID_COUNTRY")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Country country;
    @JoinColumn(name = "SEX", referencedColumnName = "ID_SEX")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Sex sex;
    @JoinColumn(name = "USER", referencedColumnName = "ID_USER")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private User user;

    public Candidate() {
        candidateEducationalInfoList=new ArrayList<CandidateEducationalInfo>();
        candidateInterestAreaList=new ArrayList<CandidateInterestArea>();
        candidateLanguageInfoList=new ArrayList<CandidateLanguageInfo>();
        candidateProfessionalInfoList=new ArrayList<CandidateProfessionalInfo>();
        candidateRelocatingInfoList=new ArrayList<CandidateRelocatingInfo>();
    }

    public Candidate(Integer idCandidate) {
        this.idCandidate = idCandidate;
    }

    public Candidate(Integer idCandidate, String name, String lastName, Date birthDay, long height, long weight, String bustColor, String bustBlackWhite, String bodyFormal, String bodyUnformal, Date lastModificationDate) {
        this.idCandidate = idCandidate;
        this.name = name;
        this.lastName = lastName;
        this.birthDay = birthDay;
        this.height = height;
        this.weight = weight;
        this.bustColor = bustColor;
        this.bustBlackWhite = bustBlackWhite;
        this.bodyFormal = bodyFormal;
        this.bodyUnformal = bodyUnformal;
        this.lastModificationDate = lastModificationDate;
    }

    public Integer getIdCandidate() {
        return idCandidate;
    }

    public void setIdCandidate(Integer idCandidate) {
        this.idCandidate = idCandidate;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Long getHeight() {
        return height;
    }

    public void setHeight(Long height) {
        this.height = height;
    }

    public Long getWeight() {
        return weight;
    }

    public void setWeight(Long weight) {
        this.weight = weight;
    }

    public String getBustColor() {
        return bustColor;
    }

    public void setBustColor(String bustColor) {
        this.bustColor = bustColor;
    }

    public String getBustBlackWhite() {
        return bustBlackWhite;
    }

    public void setBustBlackWhite(String bustBlackWhite) {
        this.bustBlackWhite = bustBlackWhite;
    }

    public String getBodyFormal() {
        return bodyFormal;
    }

    public void setBodyFormal(String bodyFormal) {
        this.bodyFormal = bodyFormal;
    }

    public String getBodyUnformal() {
        return bodyUnformal;
    }

    public void setBodyUnformal(String bodyUnformal) {
        this.bodyUnformal = bodyUnformal;
    }

    public Date getLastModificationDate() {
        return lastModificationDate;
    }

    public void setLastModificationDate(Date lastModificationDate) {
        this.lastModificationDate = lastModificationDate;
    }

    public Town getTown() {
        return town;
    }

    public void setTown(Town town) {
        this.town = town;
    }

    public Province getProvince() {
        return province;
    }

    public void setProvince(Province province) {
        this.province = province;
    }

    public Country getCountry() {
        return country;
    }

    public void setCountry(Country country) {
        this.country = country;
    }

    public Sex getSex() {
        return sex;
    }

    public void setSex(Sex sex) {
        this.sex = sex;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (idCandidate != null ? idCandidate.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Candidate)) {
            return false;
        }
        Candidate other = (Candidate) object;
        if ((this.idCandidate == null && other.idCandidate != null) || (this.idCandidate != null && !this.idCandidate.equals(other.idCandidate))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "entities.Candidate[ idCandidate=" + idCandidate + " ]";
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public CandidateType getCandidateType() {
        return candidateType;
    }

    public void setCandidateType(CandidateType candidateType) {
        this.candidateType = candidateType;
    }

    public CandidateEconomicType getCandidateEconomicType() {
        return candidateEconomicType;
    }

    public void setCandidateEconomicType(CandidateEconomicType candidateEconomicType) {
        this.candidateEconomicType = candidateEconomicType;
    }

    @XmlTransient
    public List<CandidateEducationalInfo> getCandidateEducationalInfoList() {
        return candidateEducationalInfoList;
    }

    public void setCandidateEducationalInfoList(List<CandidateEducationalInfo> candidateEducationalInfoList) {
        this.candidateEducationalInfoList = candidateEducationalInfoList;
    }

    @XmlTransient
    public List<CandidateProfessionalInfo> getCandidateProfessionalInfoList() {
        return candidateProfessionalInfoList;
    }

    public void setCandidateProfessionalInfoList(List<CandidateProfessionalInfo> candidateProfessionalInfoList) {
        this.candidateProfessionalInfoList = candidateProfessionalInfoList;
    }

    @XmlTransient
    public List<CandidateLanguageInfo> getCandidateLanguageInfoList() {
        return candidateLanguageInfoList;
    }

    public void setCandidateLanguageInfoList(List<CandidateLanguageInfo> candidateLanguageInfoList) {
        this.candidateLanguageInfoList = candidateLanguageInfoList;
    }

    @XmlTransient
    public List<CandidateInterestArea> getCandidateInterestAreaList() {
        return candidateInterestAreaList;
    }

    public void setCandidateInterestAreaList(List<CandidateInterestArea> candidateInterestAreaList) {
        this.candidateInterestAreaList = candidateInterestAreaList;
    }

    @XmlTransient
    public List<CandidateRelocatingInfo> getCandidateRelocatingInfoList() {
        return candidateRelocatingInfoList;
    }

    public void setCandidateRelocatingInfoList(List<CandidateRelocatingInfo> candidateRelocatingInfoList) {
        this.candidateRelocatingInfoList = candidateRelocatingInfoList;
    }

    public TimeAvailability getTimeAvailability() {
        return timeAvailability;
    }

    public void setTimeAvailability(TimeAvailability timeAvailability) {
        this.timeAvailability = timeAvailability;
    }

    public Integer getVisits() {
        return visits;
    }

    public void setVisits(Integer visits) {
        this.visits = visits;
    }

    @XmlTransient
    public List<CompanyAdquiredProfile> getCompanyAdquiredProfileList() {
        return companyAdquiredProfileList;
    }

    public void setCompanyAdquiredProfileList(List<CompanyAdquiredProfile> companyAdquiredProfileList) {
        this.companyAdquiredProfileList = companyAdquiredProfileList;
    }

    public Boolean getHasVehicle() {
        return hasVehicle;
    }

    public void setHasVehicle(Boolean hasVehicle) {
        this.hasVehicle = hasVehicle;
    }

    @XmlTransient
    public List<CandidateBookImage> getCandidateBookImageList() {
        return candidateBookImageList;
    }

    public void setCandidateBookImageList(List<CandidateBookImage> candidateBookImageList) {
        this.candidateBookImageList = candidateBookImageList;
    }

    public WorkingStatus getWorkingStatus() {
        return workingStatus;
    }

    public void setWorkingStatus(WorkingStatus workingStatus) {
        this.workingStatus = workingStatus;
    }

    @XmlTransient
    public List<CompanyVisitedProfile> getCompanyVisitedProfileList() {
        return companyVisitedProfileList;
    }

    public void setCompanyVisitedProfileList(List<CompanyVisitedProfile> companyVisitedProfileList) {
        this.companyVisitedProfileList = companyVisitedProfileList;
    }
    
    public List<Sector> getDifferentProfessionalTargetSectors(){
        List<Sector> differentSectors=new ArrayList<Sector>();
        for (CandidateProfessionalInfo professionalInfo : getCandidateProfessionalInfoList()) {
            if(!differentSectors.contains(professionalInfo.getSector())){
                differentSectors.add(professionalInfo.getSector());
            }
        }
        for (CandidateEducationalInfo educationalInfo : getCandidateEducationalInfoList()) {
            if(!differentSectors.contains(educationalInfo.getSector())){
                differentSectors.add(educationalInfo.getSector());
            }
        }
        return differentSectors;
    }
    
    public Integer getYearsOld(){
        Date now=new Date();
        long diff=now.getTime()-this.getBirthDay().getTime();
        long days=diff / 1000 / 60 / 60 / 24 / 365;
        return (int)days;
    }


    public CandidateConfiguration getCandidateConfiguration() {
        return candidateConfiguration;
    }

    public void setCandidateConfiguration(CandidateConfiguration candidateConfiguration) {
        this.candidateConfiguration = candidateConfiguration;
    }

    public PublicRelationsCandidate getPublicRelationsCandidate() {
        return publicRelationsCandidate;
    }

    public void setPublicRelationsCandidate(PublicRelationsCandidate publicRelationsCandidate) {
        this.publicRelationsCandidate = publicRelationsCandidate;
    }

    @XmlTransient
    public List<CandidateTags> getCandidateTagsList() {
        return candidateTagsList;
    }

    public void setCandidateTagsList(List<CandidateTags> candidateTagsList) {
        this.candidateTagsList = candidateTagsList;
    }

    @XmlTransient
    public List<CandidateSearchInterest> getCandidateSearchInterestList() {
        return candidateSearchInterestList;
    }

    public void setCandidateSearchInterestList(List<CandidateSearchInterest> candidateSearchInterestList) {
        this.candidateSearchInterestList = candidateSearchInterestList;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
    
    public Boolean getIsValid() {
        return (idCandidate!=null)&&(name!=null)&&(lastName!=null)&&(birthDay!=null)&&(bustColor!=null);
    }
    
    public String getSearcheableKeywordString(){
        StringBuilder sb=new StringBuilder();
        if(this.getDescription()!=null){
            sb.append(this.getDescription());
            sb.append(" ");
        }
        if(candidateProfessionalInfoList!=null){
            for (CandidateProfessionalInfo candidateProfessionalInfo : candidateProfessionalInfoList) {
                if(candidateProfessionalInfo.getCompany()!=null){
                    sb.append(candidateProfessionalInfo.getCompany());
                    sb.append(" ");
                }
                if(candidateProfessionalInfo.getDescription()!=null){
                    sb.append(candidateProfessionalInfo.getDescription());
                    sb.append(" ");
                }
            } 
        }
        if(candidateEducationalInfoList!=null){
            for (CandidateEducationalInfo candidateEducationalInfo : candidateEducationalInfoList) {
                if(candidateEducationalInfo.getDescription()!=null){
                    sb.append(candidateEducationalInfo.getDescription());
                    sb.append(" ");
                }
            }
        }
        if(getCandidateTagsList()!=null){
            for (CandidateTags candidateTag : candidateTagsList) {
                sb.append(candidateTag);
                sb.append(" ");
            }
        }
        
        return sb.toString();
        
    }

    @Override
    public Candidate getCandidate() {
        return this;
    }

    @Override
    public int compareTo(Candidate candidate) {
        int res=0;
        res=candidate.getVisits().compareTo(this.getVisits());
        if(res==0){
            res=candidate.getUser().getLastDate().compareTo(this.getUser().getLastDate());
            if(res==0){
                res=new Integer(candidate.getUser().getLogins()).compareTo(this.getUser().getLogins());
            }
        }
        return res;
    }
    
}
